/*
 * Matthew Cramer, Jesse Martinez, Marc Mendoza 
 * CSE 325 Lab 2
 * File: TestingInterface.c
 * Description: Manager that handles calls to the Queue.  This is called from
 *              the Process manager to perform the functions to the stack.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "QueueManager.h"
#include "ProcessManager.h"

void list(int);

int main(int argc, char *argv[])
{
	char command[80], argument[6][10];
	char *temp;
	int exit = 1, check, manualInput = 1;
	FILE *file;
	
	if(argc == 2)
	{
		file = fopen ( argv[1], "r" );
		manualInput = 0;
	}
	
	initializeQueues();
	
	while(exit != 0)
	{
		printf("\nProcess Manager: \n");
		printf("1) create [pid | psw | page-table | reg0 | reg1 | reg2]\n");
		printf("2) list [queue_name | all | SCHED]\n");
		printf("3) unwait [pid]\n");
		printf("4) eoquantum\n");
		printf("5) eolife\n");
		printf("6) wait\n");
		printf("7) go\n");
		printf("8) resetQueues\n");
		printf("9) exit\n");
        printf("\n ");
		
		//waits for user to input commands
		if(manualInput == 1)
		{
			scanf("%[^\n]", command);
			getchar();
		}

		//pulls in commands from a file
		else if(manualInput == 0)
		{
			fgets(command, sizeof command, file);
			printf("%s\n", command);
		}
		
		//uses a string tokenizer to split files based on whitespace
		temp = strtok(command, " ");
		strcpy(command, temp);

		//new process is create by calling toNew and will receive -1 or -8 if there is an error
		if(strcmp(command, "create") == 0)
		{
			int i = 0;
			temp = strtok(NULL, " ");

			//the [pid | psw |[age-table |reg0 |reg 1 | reg2] is extracted from input
			while(i < 6)
			{
				strcpy(argument[i], temp);
				if(i != 5)
					temp = strtok(NULL, " ");
				i++;
			}
			
			check = toNew(atoi(argument[0]), atoi(argument[1]), atoi(argument[2]), atoi(argument[3]),
				atoi(argument[4]), atoi(argument[5]));
			if(check == -8 || check == -1)
				printf("ERROR: Max number of processes running\n");
			else
				printf("Process %s created\n", argument[0]); 
		}

		//based on which queue is to be listed, list() is called with number
		//corresponding to queue
		else if(strcmp(command, "list") == 0)
		{
			temp = strtok(NULL, " "); //get attribute of list
			
			if(strcmp(temp, "new") == 0)
				list(1);
			else if(strcmp(temp, "ready") == 0)
				list(2);
			else if(strcmp(temp, "running") == 0)
				list(3);
			else if(strcmp(temp, "wait") == 0)
				list(4);
			else if(strcmp(temp, "terminate") == 0)
				list(5);
            else if(strcmp(temp, "SCHED") == 0)
            {
                int headSched = getHead(2);
                process_control_block *tempQueue1 = getQueue(2);
                if(headSched != -1)
                {
                printf("Next Scheduled Process:\n");
                printf("PID: %d\nPSD: %d\nPage Table: %d\nReg1: %d\nReg2: %d\nReg3: %d\n",
                       tempQueue1[headSched].pid,
                       tempQueue1[headSched].psw,
                       tempQueue1[headSched].pageTable,
                       tempQueue1[headSched].regs[0],
                       tempQueue1[headSched].regs[1],
                       tempQueue1[headSched].regs[2]);
                }
                else
                {
                    printf("No Process Scheduled Next\n");
                }
            }
			else if(strcmp(temp, "all") == 0)
			{
				int i = 0;
				for(i=1; i < 6; i++) 
				{
					list(i);
                    printf("\n");
				}
			}
		}

		//unwaiting a process has the possibility of two errors:
		//-process not found
		//-process unable to moved into ready
		else if(strcmp(command, "unwait") == 0)
		{
			temp = strtok(NULL, " ");
			check = processManagerFunction(1, (atoi(temp)));
			if(check == -2)
				printf("ERROR: Process not found\n");
			else if(check == -3)
				printf("ERROR: Process could not be moved from the Waiting to Ready queue\n");
			else
				printf("Process was moved to the Ready queue successfully");
		}

		//process is moved from running to ready
		else if(strcmp(command, "eoquantum") == 0)
		{
			check = processManagerFunction(2, 0);
			
			if(check == -4)
				printf("ERROR: Process could not be moved from the Running to Ready queue\n");
			else
				printf("Running process successfully moved to Ready queue\n");
		}

		//process is terminated
		else if(strcmp(command, "eolife") == 0)
		{
			check = processManagerFunction(3, 0);
			
			if(check == -5)
				printf("ERROR: Process could not be terminated\n");
			else
				printf("Process %d was terminated successfully", check);
		}
		
		//process is moved from running to waiting
		else if(strcmp(command, "wait") == 0)
		{
			check = processManagerFunction(4, 0);
			
			if(check == -6)
				printf("ERROR: Process could not be placed into waiting\n");
			else
				printf("Process was placed into wait queue successfully");
		}

		else if(strcmp(command, "go") == 0) //1 for processManagerFunction
		{
			check = processManagerFunction(0, 0);
			if(check == -7)
				printf("ERROR: There are no processes ready to be run\n");
			else
				printf("go was succcessful\n");
		}
		
		else if(strcmp(command, "resetQueues") == 0) //1 for processManagerFunction
		{
			clearQueues();
			printf("Queues were reset\n");
		}
		
		else if(strcmp(command, "exit") == 0)
		{
			exit = 0;
		}
	}

	return 0;
}

//prints list based on which number is passed
void list(int whichQueue)
{
	int head = getHead(whichQueue), tail = getTail(whichQueue);
	process_control_block *tempQueue = getQueue(whichQueue);
	
	if(whichQueue == 1)
		printf("New Queue:\n");
	else if(whichQueue == 2)
		printf("Ready Queue:\n");
	else if(whichQueue == 3)
		printf("Running Queue:\n");	
	else if(whichQueue == 4)
		printf("Wait Queue:\n");
	else if(whichQueue == 5)
		printf("Terminate Queue:\n");
	
	if(head == -1)
		printf("Empty\n");
		
	//iterates through queue
	else
	{
		int i = head;
		while(i != -1)
		{
			printf("Process ID: %d\n", tempQueue[i].pid);
			i = tempQueue[i].nextIndex;
		}
	}
}
